﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using Common;
using Dal;
using LuceneManager;


namespace ResultManagement
{
    public class ResultManager
    {

        string _prefixFilePath;
        IndexNode[] _indexNodes;

        public ResultManager(LuceneSettings ls)
        {

            _prefixFilePath = ls.PrefixFilePath;
            _indexNodes = ls.IndexNodes;
        }

        //Returns only documents matching one of the doc types specified.
        public List<Document> FilterResultsByDocumentTypes(List<Document> docs, List<Document.Type> docTypes)
        {
            List<Document> res = new List<Document>();
            foreach (Document doc in docs)
            {
                if (docTypes.Contains(doc.DocType))
                    res.Add(doc);
            }
            return res;
        }

        public List<Document> GetUserCategoryResults(string userName,
          Category category, bool IsRead)
        {
            int temp;
            return GetUserCategoryResults(userName, category.Queries, category, IsRead, -1, -1, out temp);
        }
        public List<Document> GetUserCategoryResults(string userName,
          Category category, bool IsRead,  int fromDocIndex, int toDocIndex)
        {
            int temp;
            return GetUserCategoryResults(userName, category.Queries, category, IsRead, -1, -1, out temp);
        }

        public List<Document> GetUserCategoryResults(string userName,
           List<string> queries, Category category, bool IsRead)
        {
            int temp;
            return GetUserCategoryResults(userName, queries, category, IsRead, -1, -1, out temp);
        }

        //Gets list of documents including excerpts for all of the user's queries in category.
        public List<Document> GetUserCategoryResults(string userName,
            List<string> queries, Category category, bool IsRead, 
            int fromDocIndex, int toDocIndex, out int totalDocNumber)
        {

            Hashtable DocQueries = new Hashtable();
            DatabaseAbstractionLayer Dal = new DatabaseAbstractionLayer();
            User user = Dal.GetUserByUserName(userName);
            HebrewStemmer hs = new HebrewStemmer(_prefixFilePath);
            LuceneReader reader = new LuceneReader(_indexNodes);
            totalDocNumber = 0; //In case no docs are returned     

            //For each user query, get list of documents that were a match.
            foreach (string query in queries)
            {
                List<Document> res = new List<Document>();
                Dictionary<long, float> kvpDocScore = new Dictionary<long, float>();
                if (!IsRead)
                {
                    kvpDocScore = Dal.GetUserSearchResultsByQuery(user, query, IsRead);
                    foreach (KeyValuePair<long, float> kvp in kvpDocScore)
                    {
                        Document doc = reader.GetDocumentById(kvp.Key);
                        doc.Score = kvp.Value;
                        res.Add(doc);
                    }
                    totalDocNumber = kvpDocScore.Count;
                }
                else //TODO: this is LAME!!!
                {
                     res = reader.GetDocumentsMatchingQuery(query, fromDocIndex, 
                         toDocIndex, out totalDocNumber);
                }
        



                //Make a hash of - Key: Document, Value: Query List within this document.
                //This is for displaying multiple query results in one document.
                foreach (Document doc in res)
                {
                    if (!category.IsDocumentTypeRequested(doc.DocType)) continue;
                    if (DocQueries.ContainsKey(doc))
                    {
                        if (DocQueries[doc] as List<string> == null)
                        {
                            List<string> queryList = new List<string>();
                            queryList.Add(query);
                            DocQueries[doc] = queryList;
                        }
                        else
                            (DocQueries[doc] as List<string>).Add(query);
                    }
                    else
                    {
                        List<string> queryList = new List<string>();
                        queryList.Add(query);
                        DocQueries.Add(doc, queryList);
                    }
                }
            }

            List<Document> result = new List<Document>();

            //Each document gets its excerpts (according to the queries it matches).
            int i = 0;
            foreach (DictionaryEntry e in DocQueries)
            {
                Document doc = e.Key as Document;

                //Get Excerpts for each document
                if (fromDocIndex > -1 && toDocIndex > -1 && fromDocIndex < toDocIndex)
                {
                    if (i >= fromDocIndex && i <= toDocIndex)
                    {
                        doc.Excerpts =
                           //doc.GetHTMLExcerpts(((List<string>)DocQueries[doc]).ToArray(),
                    //Document.Section.Text, 1, 7, 7, hs);
                       reader.GetHTMLExcerpts(((List<string>)DocQueries[doc]), doc, _prefixFilePath);
                    }
                    i++;
                }
                else
                    reader.GetHTMLExcerpts(((List<string>)DocQueries[doc]), doc, _prefixFilePath);
                   
                //Get Display Name for each document
                doc.DisplayNameProperty = doc.GetDocumentDisplayName(Dal.GetSiteNames(doc.SiteName));
                //Get Priority for this category.
                doc.SitePriority = category.GetPriorityBySiteName(doc.SiteName);
                result.Add(doc);
            }
            //lm.CloseAllFiles();
                 return result;
        }

        public List<Document> GetExcerpts(List<Document> docs, List<string> queries,
            int fromDocIndex, int toDocIndex)
        {
            LuceneManager.LuceneReader reader = new LuceneReader(_indexNodes);
            HebrewStemmer hs = new HebrewStemmer(_prefixFilePath);
            //Get Excerpts for each document
            int i = 0;
            //Excerpts to some.
            if (fromDocIndex > -1 && toDocIndex > -1 && fromDocIndex < toDocIndex)
            {
                foreach (Document doc in docs)
                {

                    if (i >= fromDocIndex && i <= toDocIndex)
                    {
                        //doc.Excerpts =
                        //   doc.GetHTMLExcerpts(queries.ToArray(),
                   // Document.Section.Text, 1, 7, 7, hs);
                        doc.Excerpts = reader.GetHTMLExcerpts(queries, doc, _prefixFilePath);
                    }
                    i++;
                }
            }
            else //Exceprts to all
                foreach (Document doc in docs)
                {
                    doc.Excerpts = reader.GetHTMLExcerpts(queries, doc, _prefixFilePath);
                }
        
            return docs;
        }

    }
}
